#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

void imprimirerro(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[]){
    
	// Variáveis globais
	int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

	// Variável que diz se o programa irá retornar feedback ao usuário
	int verb = 1;

	// Buffer do endereço destinatário e da mensagem
    char bufferDEST[100];
    char bufferMSG[256];
	
	// Ajuda
    if (argc < 3) {
       printf("\n- Ajuda ---------------------------------\n");
	   fprintf(stderr,"Use %s host porta [verb]\n\n", argv[0]);
	   printf("	host  - Nome do Host Server ou IP.\n");
	   printf("	porta - Porta em que o serviço roda.\n\n");
	   printf("	verb - 0 para esconder logs.\n\n");
	   printf("	       * para apresentar logs.\n\n");
	   printf("-----------------------------------------\n\n");
       exit(0);
    }    
	
	// Verifica se o usuário quer os logs de feedback
	if (argc == 4)
		if (atoi(argv[3]) == 0)
			verb = 0;
	
	//numero da porta
	portno = atoi(argv[2]);
	
	// Iniciar SOCKET -----------------------
	if ( verb != 0 )
		printf("\n1 - Iniciando SOCKET: ");
	
    sockfd = socket(AF_INET, SOCK_STREAM, 6);    
	
	if (sockfd < 0) 
		imprimirerro("ERRO ao abrir SOCKET.\nVerifique se o host e a porta estão corretos.\n");
	
	if ( verb != 0 )
		printf("OK!\n");
	// --------------------------------------	
	
	// Verificar HOST -----------------------
	if ( verb != 0 )
		printf("\n2 - Verificando HOST %s: ", argv[1]);
    
	server = gethostbyname(argv[1]);
    
	if (server == NULL) {
        fprintf(stderr,"ERRO, host não encontrado.\nVerifique se o host está respondendo corretamente.\n");
        exit(0);
    }
	
	if ( verb != 0 )
		printf("OK!\n");
	// --------------------------------------
	
	// Conecta com o Servidor ---------------
	if ( verb != 0 )
		printf("\n3 - Iniciando conexão com (SERVIDOR:PORTA) %s:%s : ", argv[1], argv[2]);
    
	bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);

    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        imprimirerro("ERRO de conexão.\n");
	
	if ( verb != 0 )
		printf("OK!\n");
    // --------------------------------------
   
	// Solicita mensagem --------------------
	printf("\n\n4 - Por favor, entre com a mensagem: ");    
	bzero(bufferMSG,256);
    fgets(bufferMSG,255,stdin);
    // --------------------------------------

	// Enviar Mensagem para o SOCKET --------
	if ( verb != 0 )
		printf("\n\n6 - Enviando Mensagem para SERVIDOR SOCKET: ");
	
	n = write(sockfd,bufferMSG,strlen(bufferMSG));
    if (n < 0)
        imprimirerro("ERRO ao escrever para o SERVIDOR SOCKET.\n");
	
	if ( verb != 0 )
		printf("OK! Mensagem enviada para o SERVIDOR SOCKET!\n");
    // --------------------------------------

	// Solicita Destinatario ----------------
	printf("\n\n5 - Por favor, entre com o e-mail do destinatário: ");
	bzero(bufferDEST,100);
    fgets(bufferDEST,99,stdin);
    // --------------------------------------
	
	// Enviar Destinatário para o SOCKET ----
	if ( verb != 0 )
		printf("\n\n7 - Enviando E-mail do Destinatário para o SERVIDOR SOCKET: ");
	
	n = write(sockfd,bufferDEST,strlen(bufferDEST));
    if (n < 0)
        imprimirerro("ERRO ao escrever para o SERVIDOR SOCKET.\n");
	
	if ( verb != 0 )
		printf("OK! E-mail do Destinatário enviado para o SERVIDOR SOCKET!\n");
    // --------------------------------------
	
	bzero(bufferMSG,256);
    
	// Resposta do SOCKET -------------------
	if ( verb != 0 )
		printf("\n8 - Esperando confirmação do SERVIDOR SOCKET: ");
	
	n = read(sockfd,bufferMSG,255);    
	if (n < 0)
        imprimirerro("ERRO ao ler do SOCKET.\n");
	
	if ( verb != 0 )
		printf("OK! SERVIDOR SOCKET recebeu a resporta e responde: ");
    // --------------------------------------
	
	// Resposta do TCP ----------------------
	printf("\n\n	RESPOSTA SERVIDOR SOCKET: %s\n\n\n",bufferMSG);
    // --------------------------------------
	
	// Fecha o SOCKET -----------------------
	if ( verb != 0 )
		printf("\n9 - Encerrando conexão e CLIENTE SOCKET: ");
	
	close(sockfd);
	
	if ( verb != 0 )
		printf("OK!\n\n");
    // --------------------------------------
	
	return 0;
}
